<!DOCTYPE html>
<html>

	<head>
		<title>生成二维码</title>
		<meta http-equiv="content-type" content="text/html;charset=UTF-8">

	</head>

	<body>
		<canvas id='canvas' width='300' height='300' style='background:#cccccc'></canvas>
	</body>
	<script>
		var ctx = document.getElementById('canvas').getContext('2d');
		//设置线宽
		ctx.lineWidth = 3;
		//设置画笔颜色
		//设置画笔颜色
		ctx.strokeStyle = 'red';
		//设置填充颜色
		ctx.fillStryle = '#765675';
		//设置线段末端样式
		//ctx.lineCap = "round";
		//定义圆弧起点
		var qidian = -Math.PI * 3 / 4;
		//定义圆弧终点变量
		var zhongdian = -Math.PI * 3 / 4;

		//定义快照图
		ctx.beginPath();
		ctx.strokeStyle = '#eee';
		ctx.arc(150, 150, 50, 0, Math.PI * 2, false);
		ctx.stroke()
		var base = ctx.getImageData(0, 0, 300, 300) //保存快照
		ctx.clearRect(0, 0, 300, 300)

		//画笔颜色还原
		ctx.strokeStyle = 'rgba(234,34,34,1)';

		//设置定时调用，形成动画
		var timerId = setInterval(function() {
				//当终点位置涨到大于math.pi*6/4时，停止动画
				if(zhongdian < Math.PI * 5 / 4) {
					//增长部分
					//清画布
					ctx.clearRect(0, 0, 300, 300);
					ctx.putImageData(base, 0, 0); //取出快照

					//为了做圆形渐变，这里分2部分处理
					if(zhongdian < Math.PI / 180 * 45) {
						//清空路经过列表
						ctx.beginPath();
						//计算起点，终点
						var qidian_x = 150 + 50 * Math.cos(-(qidian));
						var qidian_y = 150 - 50 * Math.sin(-(qidian));
						var zhongdian_x = 150 + 50 * Math.cos(-zhongdian);
						var zhongdian_y = 150 - 50 * Math.sin(-zhongdian);
						//设置渐变
						var lineargradient = ctx.createLinearGradient(qidian_x, qidian_y, zhongdian_x, zhongdian_y);
						lineargradient.addColorStop(0, 'rgba(234,34,34,0)');
						lineargradient.addColorStop(1, 'rgba(234,34,34,1)');
						ctx.strokeStyle = lineargradient;
						//画圆弧
						ctx.arc(150, 150, 50, qidian, zhongdian, false);
						//渲染画笔
						ctx.stroke()

					} else {
						//清空路经过列表
						ctx.beginPath();
						//计算第一阶段起点，终点
						var qidian_x = 150 + 50 * Math.cos(-(qidian));
						var qidian_y = 150 - 50 * Math.sin(-(qidian));
						var zhongdian_x = 150 + 50 * Math.cos(-(qidian + 180 * (Math.PI / 180)));
						var zhongdian_y = 150 - 50 * Math.sin(-(qidian + 180 * (Math.PI / 180)));
						//设置渐变
						var lineargradient = ctx.createLinearGradient(qidian_x, qidian_y, zhongdian_x, zhongdian_y);
						lineargradient.addColorStop(0, 'rgba(234,34,34,0)');
						lineargradient.addColorStop(1, 'rgba(234,34,34,' + (qidian + Math.PI) / zhongdian + ')'); //这里的终点透明度，应该是个根据占比变化的值，而不是简单的0.5
						ctx.strokeStyle = lineargradient;
						//画圆弧
						ctx.arc(150, 150, 50, qidian, (qidian + 180 * (Math.PI / 180)), false);
						//渲染第一阶段圆弧
						ctx.stroke()

						//计算第二阶段起点终点坐标，起点就是第一阶段的终点
						var zhongdian1_x = 150 + 50 * Math.cos(-(zhongdian));
						var zhongdian1_y = 150 - 50 * Math.sin(-(zhongdian));

						//设置渐变
						var lineargradient = ctx.createLinearGradient(zhongdian_x, zhongdian_y, zhongdian1_x, zhongdian1_y);
						lineargradient.addColorStop(0, 'rgba(234,34,34,' + (qidian + Math.PI) / zhongdian + ')'); //这里的起点透明度，应该是个根据占比变化的值，而不是简单的0.5
						lineargradient.addColorStop(1, 'rgba(234,34,34,1)');
						ctx.strokeStyle = lineargradient;
						//清空上面的路径
						ctx.beginPath();
						//画圆弧
						ctx.arc(150, 150, 50, (qidian + 180 * (Math.PI / 180)), zhongdian, false);
						//渲染第二阶段圆弧
						ctx.stroke()

					}
					//终点生长
					zhongdian += 0.02
				}
			},
			10);
	</script>

</html>